package com.zmn.oms.third.zhimi.service.impl;

import com.alibaba.fastjson.JSON;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.constant.StatusConsts;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.business.interfaces.notifylog.OrderNotifyLogBService;
import com.zmn.oms.business.interfaces.remark.OrderRemarkBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderLogConsts;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.master.OrderMaster;
import com.zmn.oms.model.entity.notifylog.OrderNotifyLog;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.orderattachment.OrderAttachment;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItem;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.entity.work.OrderWorkLogChange;
import com.zmn.oms.model.vo.remark.OrderRemarkDetailVO;
import com.zmn.oms.model.vo.remark.OrderRemarkVO;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.master.OrderMasterService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.orderattachment.OrderAttachmentService;
import com.zmn.oms.services.interfaces.serviceitem.OrderServiceItemService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.third.base.dto.api.ApiInvokResult;
import com.zmn.oms.third.base.util.MasterPhoneUtil;
import com.zmn.oms.third.zhimi.ZhimiApiInvoker;
import com.zmn.oms.third.zhimi.ZhimiConsts;
import com.zmn.oms.third.zhimi.api.ZhimiSyncOrderCompleteReq;
import com.zmn.oms.third.zhimi.api.ZhimiSyncOrderStatusReq;
import com.zmn.oms.third.zhimi.entity.ZhimiOrderExtend;
import com.zmn.oms.third.zhimi.service.ZhimiOrderExtendService;
import com.zmn.oms.third.zhimi.service.ZhimiOrderNotifyService;
import com.zmn.oms.zmn.business.interfaces.open.OrderChangeNotifyService;
import com.zmn.oms.zmn.business.interfaces.open.OrderNewNotifyService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 类描述：
 *
 * @author lhl
 * @date 2020/04/27 18:02
 */
@Slf4j
@Service("zhimiOrderNotifyService")
public class ZhimiOrderNotifyServiceImpl implements OrderChangeNotifyService, OrderNewNotifyService, ZhimiOrderNotifyService {

    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private OrderServiceItemService orderServiceItemService;
    @Autowired
    private OrderLogBService orderLogBService;
    @Autowired
    private OrderMasterService orderMasterService;
    @Autowired
    private OrderNotifyLogBService orderNotifyLogBService;
    @Autowired
    private WorkFlowContextBService workFlowContextBService;
    @Autowired
    private OrderExtendService orderExtendService;
    @Autowired
    private OrderAttachmentService orderrderAttachmentService;
    @Autowired
    private OrderRemarkBService orderRemarkBService;
    @Autowired
    private ZhimiOrderExtendService zhimiOrderExtendService;


    @Override
    public void notifyChange(OrderWorkLogChange orderWorkLogChange) throws OmsBaseException {
        int logType = orderWorkLogChange.getLogType().intValue();

        // 修改/确认
        if (OrderLogConsts.ORDER_LOG_TYPE_UPDATE == logType || OrderLogConsts.ORDER_LOG_TYPE_CONFIRM == logType) {
            // 针对首次同步接单失败的情况，可通过“修改”操作，再次触发同步接单状态
            // 如果已同步过接单，不再同步
            if (!containsSuccessLog(orderWorkLogChange.getOrderId(), ZhimiConsts.SYNC_CODE_ACCEPT)) {
                syncAcceptOrder(orderWorkLogChange);
            }
        }
        // 派单
        else if (OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE == logType) {
            syncMaster(orderWorkLogChange);
        }
        // 上门
        else if (OrderLogConsts.ORDER_LOG_TYPE_VISIT == logType) {
            syncVisited(orderWorkLogChange);
        }
        // 取消、失败、弃单
        else if (OrderLogConsts.ORDER_LOG_TYPE_CANCEL == logType || OrderConsts.ORDER_OP_TYPE_FAIL == logType
                || OrderConsts.ORDER_OP_TYPE_DISCARD == logType) {
            syncOrderCancel(orderWorkLogChange);
        }

        // 同步预约时间
        if (isChangeDutyTime(logType, orderWorkLogChange)) {
            // 如果已同步过预约时间，使用改约接口
            if (containsSuccessLog(orderWorkLogChange.getOrderId(), ZhimiConsts.SYNC_CODE_DUTYTIME)) {
                syncChangeDutyTime(orderWorkLogChange);
            }
            // 首次同步过预约时间，使用预约时间接口
            else {
                syncDutyTime(orderWorkLogChange);
            }
        }

        // 修改产品，同步维护产品对应的服务类型
        if (OrderLogConsts.ORDER_LOG_TYPE_UPDATE == logType || OrderLogConsts.ORDER_LOG_TYPE_MODIFY_PRODUCT == logType) {
            Long orderId = orderWorkLogChange.getOrderId();
            OrderDetail dbOrderDetail = orderDetailService.findOrderDetailByKey(orderId);
            log.info("【{}】更改智米订单服务类型：orderId=[{}], productId=[{}]", ZhimiConsts.CHANNEL_NAME,
                    orderId, dbOrderDetail.getProductId());

            do {
                Integer serviceType = ZhimiConsts.getServiceTypeByProductId(dbOrderDetail.getProductId());
                if (serviceType == null) {
                    log.error("【{}】更改智米订单服务类型失败：orderId=[{}], 产品ID:[{}]没有对应的智米订单服务类型。",
                            ZhimiConsts.CHANNEL_NAME, orderId, dbOrderDetail.getProductId());
                    break;
                }

                zhimiOrderExtendService.updateServiceType(orderWorkLogChange.getOrderId(), serviceType);
            } while (false);
        }
    }

    @Override
    public void notifyNewOrder(OrderWorkLogChange orderWorkLogChange) throws OmsBaseException {
        syncNewOrderCallback(orderWorkLogChange);
    }

    @Override
    public ApiInvokResult notifyOrderComplete(Long orderId) {
        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderId, orderId);
        if (dbOrderWork == null) {
            return ApiInvokResult.fail("订单不存在");
        }

        OrderWorkLogChange orderWorkLogChange = new OrderWorkLogChange();
        orderWorkLogChange.setMqMsgKey("none");
        orderWorkLogChange.setOrderId(orderId);
        orderWorkLogChange.setWorkId(dbOrderWork.getWorkId());
        orderWorkLogChange.setChannelId(dbOrderWork.getChannelId());
        orderWorkLogChange.setStatus(dbOrderWork.getStatus());
        orderWorkLogChange.setResultStatus(dbOrderWork.getResultStatus());

        return syncOrderComplete(orderWorkLogChange);
    }

    /**
     * 判断是否已经同步过完成
     * @param orderId
     * @return
     */
    public boolean isSyncCompleted(Long orderId) {
        List<OrderNotifyLog> orderNotifyLogs = orderNotifyLogBService.listByOrderId(orderId);

        if (orderNotifyLogs == null || orderNotifyLogs.isEmpty()) {
            return false;
        }

        String completeStatusStr = String.valueOf(ZhimiConsts.SYNC_CODE_COMPLETE);
        for (OrderNotifyLog item : orderNotifyLogs) {
            if (completeStatusStr.equals(item.getNotifyStatus())
                    && Objects.equals(StatusConsts.STATUS_SUCCESS, item.getNotifyResultStatus())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 同步服务单回调
     *  这个回调 只是通知智米我方收到了这个服务单，下次再获取，智米就不会重复给我方了
     * @param orderWorkLogChange
     */
    private void syncNewOrderCallback(OrderWorkLogChange orderWorkLogChange) {
        // 同步服务单回调
        String content = String.format("{\"srvname\":\"%s\",\"datalines\":[{\"name\":\"%s\"}]}", ZhimiConsts.APP_ID,
                orderWorkLogChange.getOuterId());

        ApiInvokResult result = ZhimiApiInvoker.acceptOrderCallback(content);

        // 接单成功，自动流转
        if (result.isSuccess()) {
            try {
                workFlowContextBService.asyncAutoFlow(orderWorkLogChange.getOrderId(), orderWorkLogChange.getWorkId());
            } catch (Exception e) {
                log.error(String.format("【%s】订单自动流转失败：%s", ZhimiConsts.CHANNEL_NAME, e.getMessage()), e);
            }
        }

        _saveSyncResult(orderWorkLogChange, ZhimiConsts.SYNC_CODE_CALLBACK, result);
    }

    /**
     * 同步接单
     * @param orderWorkLogChange
     */
    private void syncAcceptOrder(OrderWorkLogChange orderWorkLogChange) {
        String opTimeStr = DateUtil.toString(orderWorkLogChange.getOpTime(), DateUtil.FORMAT_DEFAULT);

        ZhimiSyncOrderStatusReq orderStatusReq = new ZhimiSyncOrderStatusReq();
        orderStatusReq.setName(orderWorkLogChange.getOuterId());
        orderStatusReq.setDealstatus(1); // 1：服务商接单
        orderStatusReq.setDealtime(opTimeStr);
        orderStatusReq.setRemark("接单成功");

        ZhimiSyncOrderStatusReq.AcceptOrder acceptOrder = orderStatusReq.new AcceptOrder();
        acceptOrder.setReceivetime(opTimeStr);
        orderStatusReq.setJsondata(JSON.toJSONString(acceptOrder));

        String content = JSON.toJSONString(orderStatusReq);
        ApiInvokResult result = ZhimiApiInvoker.syncOrderStatus(content);

        _saveSyncResult(orderWorkLogChange, ZhimiConsts.SYNC_CODE_ACCEPT, result);
    }

    /**
     * 同步预约时间
     * @param orderWorkLogChange
     */
    private void syncDutyTime(OrderWorkLogChange orderWorkLogChange) {

        String opTimeStr = DateUtil.toString(orderWorkLogChange.getOpTime(), DateUtil.FORMAT_DEFAULT);
        String dutyTimeStr = DateUtil.toString(orderWorkLogChange.getDutyTime(), DateUtil.FORMAT_DEFAULT);

        ZhimiSyncOrderStatusReq orderStatusReq = new ZhimiSyncOrderStatusReq();
        orderStatusReq.setName(orderWorkLogChange.getOuterId());
        orderStatusReq.setDealstatus(14); // 14：预约成功
        orderStatusReq.setDealtime(opTimeStr);
        orderStatusReq.setRemark("预约成功");

        ZhimiSyncOrderStatusReq.DutyTime dutyTime = orderStatusReq.new DutyTime();
        dutyTime.setBooktime(dutyTimeStr);
        dutyTime.setRemark("预约成功");
        orderStatusReq.setJsondata(JSON.toJSONString(dutyTime));

        String content = JSON.toJSONString(orderStatusReq);
        ApiInvokResult result = ZhimiApiInvoker.syncOrderStatus(content);

        _saveSyncResult(orderWorkLogChange, ZhimiConsts.SYNC_CODE_DUTYTIME, result);
    }

    /**
     * 同步修改预约时间
     * @param orderWorkLogChange
     */
    private void syncChangeDutyTime(OrderWorkLogChange orderWorkLogChange) {
        String opTimeStr = DateUtil.toString(orderWorkLogChange.getOpTime(), DateUtil.FORMAT_DEFAULT);
        String dutyTimeStr = DateUtil.toString(orderWorkLogChange.getDutyTime(), DateUtil.FORMAT_DEFAULT);

        ZhimiSyncOrderStatusReq orderStatusReq = new ZhimiSyncOrderStatusReq();
        orderStatusReq.setName(orderWorkLogChange.getOuterId());
        orderStatusReq.setDealstatus(10); // 10：改约
        orderStatusReq.setDealtime(opTimeStr);
        orderStatusReq.setRemark("修改预约成功");

        ZhimiSyncOrderStatusReq.ResetDutyTime dutyTime = orderStatusReq.new ResetDutyTime();
        dutyTime.setRevisiontime(dutyTimeStr);
        dutyTime.setReason(1); // 默认为用户调整上门时间
        orderStatusReq.setJsondata(JSON.toJSONString(dutyTime));

        String content = JSON.toJSONString(orderStatusReq);
        ApiInvokResult result = ZhimiApiInvoker.syncOrderStatus(content);

        _saveSyncResult(orderWorkLogChange, ZhimiConsts.SYNC_CODE_CHANGE_DUTYTIME, result);
    }

    /**
     * 同步派单工程师信息
     * @param orderWorkLogChange
     */
    private void syncMaster(OrderWorkLogChange orderWorkLogChange) {
        String opTimeStr = DateUtil.toString(orderWorkLogChange.getOpTime(), DateUtil.FORMAT_DEFAULT);
        Long orderId = orderWorkLogChange.getOrderId();
        Long workId = orderWorkLogChange.getWorkId();

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        Integer masterId = orderWork.getMasterId();

        // 查领单工程师
        OrderMaster master = null;
        {
            List<OrderMaster> masterList = orderMasterService.listMasterByWorkId(orderId, workId);
            for (OrderMaster item : masterList) {
                if (item.getMasterId().equals(masterId)) {
                    master = item;
                    break;
                }
            }
        }

        ApiInvokResult result = null;

        if (master == null) {
            log.info("【{}】同步工程师信息失败，没找到对应工程师。 orderId：[{}]，masterId：[{}]",
                    ZhimiConsts.CHANNEL_NAME, orderId, masterId);

            result = new ApiInvokResult();
            result.setSuccess(false);
            result.setMsg(String.format("No Master found! masterId:[%d]", masterId));
        }
        else {
            ZhimiSyncOrderStatusReq orderStatusReq = new ZhimiSyncOrderStatusReq();
            orderStatusReq.setName(orderWorkLogChange.getOuterId());
            orderStatusReq.setDealstatus(7); // 7：派工工程师
            orderStatusReq.setDealtime(opTimeStr);
            orderStatusReq.setRemark(String.format("工程师 %s 已接单", master.getMasterName()));

            ZhimiSyncOrderStatusReq.DistributeOrder distributeOrder = orderStatusReq.new DistributeOrder();
            distributeOrder.setDispatchingtime(opTimeStr);
            distributeOrder.setWorkername(
                    Optional.ofNullable(master.getMasterName())
                            .filter(name -> name.length() >= 1)
                            .map(name -> String.format("%s工程师", name.substring(0,1)))
                            .orElse("工程师")
            );
            distributeOrder.setPhonenumber(MasterPhoneUtil.getSafeMasterPhone(orderWork.getCityId()));
            distributeOrder.setPhonenumber(
                    Optional.ofNullable(orderDetailService.findOrderDetailByKey(orderWork.getOrderId()))
                            .map(orderDetail -> {
                                if (Objects.equals(orderDetail.getBindStatus(), OrderConsts.BIND_STATUS_BIND)
                                        && org.apache.commons.lang3.StringUtils.isNotBlank(orderDetail.getBindTelephone())) {
                                    return orderDetail.getBindTelephone();
                                }
                                return null;
                            })
                            .orElse(MasterPhoneUtil.getSafeMasterPhone(orderWork.getCityId()))
            );
            orderStatusReq.setJsondata(JSON.toJSONString(distributeOrder));

            String content = JSON.toJSONString(orderStatusReq);
            result = ZhimiApiInvoker.syncOrderStatus(content);
        }

        _saveSyncResult(orderWorkLogChange, ZhimiConsts.SYNC_CODE_DISTRIBUTE, result);
    }

    /**
     * 同步上门
     * @param orderWorkLogChange
     */
    private void syncVisited(OrderWorkLogChange orderWorkLogChange) {
        String opTimeStr = DateUtil.toString(orderWorkLogChange.getOpTime(), DateUtil.FORMAT_DEFAULT);
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderWorkLogChange.getOrderId());

        ZhimiSyncOrderStatusReq orderStatusReq = new ZhimiSyncOrderStatusReq();
        orderStatusReq.setName(orderWorkLogChange.getOuterId());
        orderStatusReq.setDealstatus(3); // 3：服务到位
        orderStatusReq.setDealtime(opTimeStr);
        orderStatusReq.setRemark("服务到位");

        ZhimiSyncOrderStatusReq.Visited visited = orderStatusReq.new Visited();
        visited.setArrivaltime(opTimeStr);
        visited.setDepartureaddress(String.format("%s%s", orderDetail.getStreet(), orderDetail.getAddress()));
        visited.setRemark("已上门");
        orderStatusReq.setJsondata(JSON.toJSONString(visited));

        String content = JSON.toJSONString(orderStatusReq);
        ApiInvokResult result = ZhimiApiInvoker.syncOrderStatus(content);

        _saveSyncResult(orderWorkLogChange, ZhimiConsts.SYNC_CODE_VISITED, result);
    }

    /**
     * 同步取消
     * @param orderWorkLogChange
     */
    private void syncOrderCancel(OrderWorkLogChange orderWorkLogChange) {
        Long orderId = orderWorkLogChange.getOrderId();
        ZhimiOrderExtend zhimiOrderExtend = zhimiOrderExtendService.findZhimiOrderExtendByOrderId(orderId);

        ZhimiSyncOrderCompleteReq.Cancel cancel = new ZhimiSyncOrderCompleteReq.Cancel();
        cancel.setName(zhimiOrderExtend.getOuterId());
        cancel.setServicetype(ZhimiConsts.SERVICE_TYPE_CANCEL);
        // 取消原因类型
        do {
            OrderRemarkVO orderRemarkVO = orderRemarkBService.findOrderRemarkVO(orderId, orderId,
                    OrderConsts.ORDER_REMARK_TYPE_CANCEL);
            if (orderRemarkVO == null && CollectionUtils.isEmpty(orderRemarkVO.getDetailVOList())) {
                cancel.setReasontype(19);
                break;
            }

            Integer reasontype = null;
            for (OrderRemarkDetailVO item : orderRemarkVO.getDetailVOList()) {
                ZhimiConsts.CancelReason cancelReason = ZhimiConsts.getCancelReasonByZmnCancelCode(item.getMapId());
                if (cancelReason != null) {
                    reasontype = cancelReason.getCode();
                    break;
                }
            }

            cancel.setReasontype(Optional.ofNullable(reasontype).orElse(19));
        } while (false);

        String content = JSON.toJSONString(cancel);
        boolean isAc = Objects.equals(GlobalConsts.YES, zhimiOrderExtend.getAcFlag());
        ApiInvokResult result = ZhimiApiInvoker.syncOrderComplete(content, isAc);

        _saveSyncResult(orderWorkLogChange, ZhimiConsts.SYNC_CODE_CANCEL, result);
    }

    /**
     * 同步订单完成
     * @param orderWorkLogChange
     */
    private ApiInvokResult syncOrderComplete(OrderWorkLogChange orderWorkLogChange) {
        ZhimiOrderExtend zhimiOrderExtend = zhimiOrderExtendService.findZhimiOrderExtendByOrderId(
                orderWorkLogChange.getOrderId());

        if (StringUtil.isBlank(orderWorkLogChange.getOuterId())) {
            orderWorkLogChange.setOuterId(zhimiOrderExtend.getOuterId());
        }

        ApiInvokResult result = null;
        try {
            String content = buildOrderCompleteParams(orderWorkLogChange, zhimiOrderExtend);

            boolean isAc = Objects.equals(GlobalConsts.YES, zhimiOrderExtend.getAcFlag());
            result = ZhimiApiInvoker.syncOrderComplete(content, isAc);
        } catch (OmsBaseException e) {
            String errorMsg = String.format("同步订单完成失败：%s", e.getMessage());
            log.error(String.format("【%s】%s", ZhimiConsts.CHANNEL_NAME, errorMsg), e);

            result = ApiInvokResult.fail(errorMsg);
        }

        try {
            _saveSyncResult(orderWorkLogChange, ZhimiConsts.SYNC_CODE_COMPLETE, result);
        } catch (Exception e) {
            log.error(String.format("【%s】保存同步订单完成日志失败：%s", ZhimiConsts.CHANNEL_NAME, e.getMessage()), e);
        }

        return result;
    }

    /**
     * 生成同步订单完成用的请求参数
     * @param orderWorkLogChange
     * @param zhimiOrderExtend
     * @return
     */
    private String buildOrderCompleteParams(OrderWorkLogChange orderWorkLogChange, ZhimiOrderExtend zhimiOrderExtend)
            throws OmsBaseException{
        String content = null;

        String outerId = orderWorkLogChange.getOuterId();
        Long orderId = orderWorkLogChange.getOrderId();
        // 物料编码
        String productCode = zhimiOrderExtend.getHeadPartCode();
        int serviceType = zhimiOrderExtend.getServiceType();

        // 维修
        if (ZhimiConsts.SERVICE_TYPE_REPAIR == serviceType) {
            ZhimiSyncOrderCompleteReq.Repair repair = new ZhimiSyncOrderCompleteReq.Repair();
            repair.setName(outerId);
            repair.setServicetype(serviceType);
            repair.setSn(zhimiOrderExtend.getSn());
            repair.setProductcode(productCode);
            repair.setWarranty(zhimiOrderExtend.getWarranty());
            repair.setIsexistcertificate(true); // 保修凭证写死为true

            // 购机时间
            String buyDate = getBuyDate(zhimiOrderExtend.getBuyDate());
            if (StringUtil.isBlank(buyDate)) {
                buyDate = zhimiOrderExtend.getWarrantyEndTime();
            }
            repair.setBuydate(buyDate);

            // 维修照片
            repair.setUploadpics(this._getOrderPictures(orderId));

            List<ZhimiSyncOrderCompleteReq.Fault> reqFaults = _convert2OrderCompleteReqFault(zhimiOrderExtend.getFaults());
            repair.setFaultLines(reqFaults);

            List<ZhimiSyncOrderCompleteReq.Part> reqParts = _convert2OrderCompleteReqPart(zhimiOrderExtend);
            if (CollectionUtils.isEmpty(reqParts)) {
                // 没配件时，填写无用料故障编码
                List<OrderServiceItem> orderServiceItems = orderServiceItemService.listByOrderId(orderWorkLogChange.getOrderId());
                if (!CollectionUtils.isEmpty(orderServiceItems)) {
                    for (OrderServiceItem item : orderServiceItems) {
                        ZhimiConsts.NonePartsItem nonePartsItem = ZhimiConsts.getNonePartsItem(item.getServItemId());
                        if (nonePartsItem != null) {
                            ZhimiSyncOrderCompleteReq.Part noPartRepair = new ZhimiSyncOrderCompleteReq.Part();
                            noPartRepair.setRepairmethod(nonePartsItem.getCode());
                            reqParts.add(noPartRepair);
                            break;
                        }
                    }
                }
            }
            if (!CollectionUtils.isEmpty(reqParts)) {
                repair.setPartlines(reqParts);
            }

            ZhimiOrderExtend.ReturnFactoryExpress returnFactoryExpress = zhimiOrderExtend.getReturnFactoryExpress();
            if (returnFactoryExpress != null) {
                repair.setReceivenumber(returnFactoryExpress.getExpressCode());
                repair.setReceivetransfer(returnFactoryExpress.getExpressCompanyCode());
                repair.setReceivietime(returnFactoryExpress.getExpressTime());
            }

            content = JSON.toJSONString(repair);
        }
        // 退货
        else if (ZhimiConsts.SERVICE_TYPE_RETUND == serviceType) {
            /* 满足退货条件，使用退货接口数据同步；不满足退货条件，使用检测接口数据同步 */

            ZhimiOrderExtend.Retund extRetund = zhimiOrderExtend.getRetund();
            if (extRetund == null) {
                throw new OmsBaseException(String.format("缺少退货类型信息。orderId=[%d]", zhimiOrderExtend.getOrderId()));
            }
            if (zhimiOrderExtend.getFaults() == null) {
                throw new OmsBaseException(String.format("缺少故障信息。orderId=[%d]", zhimiOrderExtend.getOrderId()));
            }

            // 不满足退货条件，不予退货，使用检测接口数据格式同步完成
            if (Objects.equals(ZhimiConsts.NO, extRetund.getType())) {
                ZhimiSyncOrderCompleteReq.Detection detection = new ZhimiSyncOrderCompleteReq.Detection();
                detection.setName(outerId);
                detection.setServicetype(ZhimiConsts.SERVICE_TYPE_DETECTION);
                detection.setSn(zhimiOrderExtend.getSn());
                detection.setProductcode(productCode);
                detection.setUploadpics(this._getOrderPictures(orderId));
                detection.setFaultLines(this._convert2OrderCompleteReqFault(zhimiOrderExtend.getFaults()));
                detection.setDetectionresult("不满足退货条件，不予退货");
                content = JSON.toJSONString(detection);
            }
            // 允许退货
            else {
                ZhimiSyncOrderCompleteReq.Retund retund = new ZhimiSyncOrderCompleteReq.Retund();
                retund.setName(outerId);
                retund.setServicetype(serviceType);
                retund.setSn(zhimiOrderExtend.getSn());
                retund.setProductcode(productCode);
                retund.setUploadpics(this._getOrderPictures(orderId));
                retund.setFaultLines(this._convert2OrderCompleteReqFault(zhimiOrderExtend.getFaults()));
                retund.setReturntpe(extRetund.getType());
                // 旧件返厂物流信息
                ZhimiOrderExtend.ReturnFactoryExpress returnFactoryExpress = zhimiOrderExtend.getReturnFactoryExpress();
                retund.setReceivetransfer(returnFactoryExpress.getExpressCompanyCode());
                retund.setReceivenumber(returnFactoryExpress.getExpressCode());
                retund.setReceivietime(returnFactoryExpress.getExpressTime());

                content = JSON.toJSONString(retund);
            }
        }
        // 换机
        else if (ZhimiConsts.SERVICE_TYPE_EXCHANGE == serviceType) {
            /* 满足换机条件，使用换机接口数据同步；不满足换机条件，使用检测接口数据同步 */

            ZhimiOrderExtend.Exchange extExchange = zhimiOrderExtend.getExchange();
            if (extExchange == null) {
                throw new OmsBaseException(String.format("缺少换机类型信息。orderId=[%d]", zhimiOrderExtend.getOrderId()));
            }
            if (zhimiOrderExtend.getFaults() == null) {
                throw new OmsBaseException(String.format("缺少故障信息。orderId=[%d]", zhimiOrderExtend.getOrderId()));
            }

            // 不满足换机条件，不予换机，使用检测接口数据格式同步完成
            if (Objects.equals(ZhimiConsts.NO, extExchange.getType())) {
                ZhimiSyncOrderCompleteReq.Detection detection = new ZhimiSyncOrderCompleteReq.Detection();
                detection.setName(outerId);
                detection.setServicetype(ZhimiConsts.SERVICE_TYPE_DETECTION);
                detection.setSn(zhimiOrderExtend.getSn());
                detection.setProductcode(productCode);
                detection.setUploadpics(this._getOrderPictures(orderId));
                detection.setFaultLines(this._convert2OrderCompleteReqFault(zhimiOrderExtend.getFaults()));
                detection.setDetectionresult("不满足换机条件，不予换机");

                content = JSON.toJSONString(detection);
            }
            // 允许换机
            else {
                int exchangeType = Optional.ofNullable(extExchange.getType()).orElse(-1);
                if (exchangeType > 0 && exchangeType <= 3) {
                    // 智米在2020.10.21日晚7点调整了接口，更改了换机类型就接口的值，所以对旧值需要做修正
                    // 原先使用的值分别为：DAP=1、DOA=2、多维换机=3
                    // 更改后的值分别为：DAP=4、DOA=5、多维换机=6、商品故障=2
                    exchangeType += 3;
                }
                ZhimiSyncOrderCompleteReq.Exchange exchange = new ZhimiSyncOrderCompleteReq.Exchange();
                exchange.setName(outerId);
                exchange.setServicetype(serviceType);
                exchange.setSn(zhimiOrderExtend.getSn());
                exchange.setProductcode(productCode);
                exchange.setUploadpics(this._getOrderPictures(orderId));
                exchange.setFaultLines(this._convert2OrderCompleteReqFault(zhimiOrderExtend.getFaults()));
                exchange.setReplacementtype(exchangeType);
                exchange.setNewsn(zhimiOrderExtend.getNewSn());
                exchange.setNewproductcode(exchange.getProductcode());

                String buyDate = getBuyDate(zhimiOrderExtend.getBuyDate());
                if (StringUtil.isBlank(buyDate)) {
                    buyDate = zhimiOrderExtend.getWarrantyBeginTime();
                }
                exchange.setBuydate(buyDate);

                // 旧件返厂物流信息
                ZhimiOrderExtend.ReturnFactoryExpress returnFactoryExpress = zhimiOrderExtend.getReturnFactoryExpress();
                if (returnFactoryExpress != null) {
                    exchange.setReceivetransfer(returnFactoryExpress.getExpressCompanyCode());
                    exchange.setReceivenumber(returnFactoryExpress.getExpressCode());
                    exchange.setReceivietime(returnFactoryExpress.getExpressTime());
                }

                content = JSON.toJSONString(exchange);
            }
        }
        // 检测
        else if (ZhimiConsts.SERVICE_TYPE_DETECTION == serviceType) {
            ZhimiSyncOrderCompleteReq.Detection detection = new ZhimiSyncOrderCompleteReq.Detection();
            detection.setName(outerId);
            detection.setServicetype(serviceType);
            detection.setSn(zhimiOrderExtend.getSn());
            detection.setProductcode(productCode);
            // 照片
            detection.setUploadpics(this._getOrderPictures(orderId));

            ZhimiOrderExtend.Detection extDetection = zhimiOrderExtend.getDetection();
            if (extDetection == null) {
                throw new OmsBaseException(String.format("缺少检测信息。orderId=[%d]", zhimiOrderExtend.getOrderId()));
            }
            detection.setReturnorexchange(extDetection.getType());
            detection.setDetectionresult(extDetection.getRemark());

            if (zhimiOrderExtend.getFaults() == null) {
                throw new OmsBaseException(String.format("缺少故障信息。orderId=[%d]", zhimiOrderExtend.getOrderId()));
            }
            List<ZhimiSyncOrderCompleteReq.Fault> reqFaults = _convert2OrderCompleteReqFault(zhimiOrderExtend.getFaults());
            detection.setFaultLines(reqFaults);

            content = JSON.toJSONString(detection);
        }
        // 安装
        else if (ZhimiConsts.SERVICE_TYPE_INSTALL == serviceType) {
            /* 正常完成，使用安装接口数据同步；不能安装的，使用勘测接口数据同步 */

            // 是否满足条件，以及不满足原因
            ZhimiOrderExtend.Survey extendSurvey = zhimiOrderExtend.getSurvey();
            boolean isFail = (extendSurvey != null && Objects.equals(extendSurvey.getState(), ZhimiConsts.NO));

            // 无法安装，使用勘测接口同步
            if (isFail) {
                ZhimiSyncOrderCompleteReq.Survey survey = new ZhimiSyncOrderCompleteReq.Survey();
                survey.setName(outerId);
                survey.setServicetype(ZhimiConsts.SERVICE_TYPE_SURVEY);
                survey.setUploadpics(this._getOrderPictures(orderId));
                survey.setIsinstallationok(ZhimiConsts.FALSE);
                survey.setReason(Optional.ofNullable(extendSurvey.getRemark()).orElse("无法安装"));

                content = JSON.toJSONString(survey);
            }
            // 正常安装
            else {
                ZhimiSyncOrderCompleteReq.Install install = new ZhimiSyncOrderCompleteReq.Install();
                install.setName(outerId);
                install.setServicetype(serviceType);
                install.setSn(zhimiOrderExtend.getSn());
                install.setProductcode(productCode);
                install.setUploadpics(this._getOrderPictures(orderId));

                content = JSON.toJSONString(install);
            }
        }
        // 勘测
        else if (ZhimiConsts.SERVICE_TYPE_SURVEY == serviceType) {
            ZhimiSyncOrderCompleteReq.Survey survey = new ZhimiSyncOrderCompleteReq.Survey();
            survey.setName(outerId);
            survey.setServicetype(serviceType);

            // 照片
            survey.setUploadpics(this._getOrderPictures(orderId));

            // 是否满足条件，以及不满足原因
            ZhimiOrderExtend.Survey extendSurvey = zhimiOrderExtend.getSurvey();
            Integer status = Objects.equals(extendSurvey.getState(), ZhimiConsts.YES) ? ZhimiConsts.TRUE : ZhimiConsts.FALSE;
            survey.setIsinstallationok(status);
            survey.setReason(extendSurvey.getRemark());

            content = JSON.toJSONString(survey);
        }
        else {
            throw new OmsBaseException(String.format("无法识别该订单的服务类型。 serviceType=[{}]", serviceType));
        }


        return content;
    }

    /**
     * 获取订单的图片信息
     * @param orderId
     * @return
     */
    private String _getOrderPictures(Long orderId) {
        List<OrderAttachment> orderAttachments = orderrderAttachmentService.listAttachmentByOrderId(orderId);
        if (!CollectionUtils.isEmpty(orderAttachments)) {
            StringBuilder stringBuilder = new StringBuilder(",");

            for (OrderAttachment item : orderAttachments) {
                if (StringUtil.isBlank(item.getSrc())) {
                    continue;
                }
                String[] split = item.getSrc().split(",");
                for (String src : split) {
                    if (StringUtil.isNotBlank(src)) {
                        stringBuilder.append(src).append(",");
                    }
                }
            }

            if (stringBuilder.length() > 1) {
                return stringBuilder.substring(1);
            }
        }

        OrderExtend orderExtend = orderExtendService.findMiniOrderExtendByOrderId(orderId);
        return orderExtend.getImageSrc();
    }

    /**
     * 将故障信息转换成同步工单完成接口需要的格式
     * @param faults
     * @return
     */
    private List<ZhimiSyncOrderCompleteReq.Fault>  _convert2OrderCompleteReqFault(List<ZhimiOrderExtend.Fault> faults) {
        List<ZhimiSyncOrderCompleteReq.Fault> reqFaults = new LinkedList<>();

        if (!CollectionUtils.isEmpty(faults)) {
            for (ZhimiOrderExtend.Fault item : faults) {
                ZhimiSyncOrderCompleteReq.Fault reqFault = new ZhimiSyncOrderCompleteReq.Fault();
                reqFault.setFaultcode(item.getCode());
                reqFault.setFaultname(item.getName());

                reqFaults.add(reqFault);
            }
        }

        return reqFaults;
    }

    /**
     * 将故障信息转换成同步工单完成接口需要的格式
     * @param zhimiOrderExtend
     * @return
     */
    private List<ZhimiSyncOrderCompleteReq.Part>  _convert2OrderCompleteReqPart(ZhimiOrderExtend zhimiOrderExtend) {
        List<ZhimiSyncOrderCompleteReq.Part> reqParts = new LinkedList<>();

        List<ZhimiOrderExtend.Part> parts = zhimiOrderExtend.getParts();
        boolean isReplaceOnly = Objects.equals(zhimiOrderExtend.getReplaceOnly(), GlobalConsts.YES);
        if (!CollectionUtils.isEmpty(parts)) {
            for (ZhimiOrderExtend.Part item : parts) {
                ZhimiSyncOrderCompleteReq.Part reqPart = new ZhimiSyncOrderCompleteReq.Part();
                reqPart.setPartcode(item.getCode());
                reqPart.setPartname(item.getName());
                reqPart.setQty(item.getNumber());
                reqPart.setOldpartcode(item.getCode());
                reqPart.setOldpartname(item.getName());
                if (isReplaceOnly) {
                    reqPart.setOldsn(zhimiOrderExtend.getSn());
                    reqPart.setNewsn(zhimiOrderExtend.getNewSn());
                }
                reqParts.add(reqPart);
            }
        }

        return reqParts;
    }

    /**
     * 保存状态同步结果信息
     * @param orderWorkLogChange
     * @param orderStatus
     * @param result
     */
    private void _saveSyncResult(OrderWorkLogChange orderWorkLogChange, int orderStatus, ApiInvokResult result) {
        if (result == null) {
            return;
        }

        OrderNotifyLog orderNotifyLog = new OrderNotifyLog();
        orderNotifyLog.setMqMsgKey(orderWorkLogChange.getMqMsgKey());
        orderNotifyLog.setOrderId(orderWorkLogChange.getOrderId());
        orderNotifyLog.setChannelId(orderWorkLogChange.getChannelId());
        orderNotifyLog.setOrderStatus(orderWorkLogChange.getStatus());
        orderNotifyLog.setOrderResultStatus(orderWorkLogChange.getResultStatus());
        orderNotifyLog.setNotifyStatus(String.valueOf(orderStatus));
        orderNotifyLog.setType(OrderConsts.ORDER_NOTIFY_TYPE_CHANGE);
        orderNotifyLog.setNotifyTime(DateUtil.getNow());
        orderNotifyLog.setNotifyResultMsg(String.format("[%s]-%s",
                ZhimiConsts.getSyncCodeName(orderStatus), result.getMsg()));

        ResultDTO resultDTO = new ResultDTO();
        resultDTO.setStatus(result.isSuccess() ? StatusConsts.STATUS_SUCCESS : StatusConsts.STATUS_ERROR);
        resultDTO.setData(orderNotifyLog);

        orderNotifyLogBService.saveNotifyLog(resultDTO);
    }

    private boolean containsSuccessLog(Long orderId, int orderStatus) {
        List<OrderNotifyLog> orderNotifyLogs = orderNotifyLogBService.listByOrderId(orderId);

        if (CollectionUtils.isEmpty(orderNotifyLogs)) {
            return false;
        }

        String orderStatusStr = String.valueOf(orderStatus);
        for (OrderNotifyLog item : orderNotifyLogs) {
            if (Objects.equals(orderStatusStr, item.getNotifyStatus())
                    && Objects.equals(StatusConsts.STATUS_SUCCESS, item.getNotifyResultStatus())) {
                return true;
            }
        }

        return false;
    }

    /**
     * 获取符合格式的购机日期（兼容格式错误）
     * @param buyDateStr
     * @return
     */
    private String getBuyDate(String buyDateStr) {
        if (StringUtil.isBlank(buyDateStr)) {
            return null;
        }

        Date buyDate = DateUtil.parse(buyDateStr, DateUtil.FORMAT_DATE);
        if (buyDate != null) {
            return buyDateStr;
        }

        buyDate = DateUtil.parse(buyDateStr, DateUtil.FORMAT_DATE2);
        if (buyDate != null) {
            return DateUtil.toString(buyDate, DateUtil.FORMAT_DATE);
        }

        return null;
    }
}
